package com.demo.security.access.audit.prepost.advice;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.security.core.Authentication;
import org.springframework.util.ReflectionUtils;

import com.demo.common.AopProxyUtils;
import com.demo.security.access.audit.prepost.PostAuditAttribute;
import com.demo.security.access.audit.prepost.PreAuditAttribute;
import com.demo.security.access.audit.prepost.PrePostInvocationAuditAdvice;
import com.demo.security.annotation.audit.AuditNotes;

/**
 * 前置后置审计处理类
 * @author ryuu.kk
 *
 */
public class PrePostInvocationAuditAdviceImpl implements PrePostInvocationAuditAdvice {

	@Override
	public void before(Authentication authentication, MethodInvocation mi,
			PreAuditAttribute preAuditAttribute) {
		preAuditAttribute.getAuditModel();
		mi.getArguments();
		System.err.println("Pre-Audit" + authentication.getPrincipal() + preAuditAttribute.getAttribute());
		
	}

	@Override
	public Object after(Authentication authentication, MethodInvocation mi,
			PostAuditAttribute postAuditAttribute, Object returnObject) {
		postAuditAttribute.getAuditModel();
		mi.getArguments();
		Method method = mi.getMethod();
		
		//ReflectionUtils.findField(clazz, name)
		Field[] fields = AopUtils.getTargetClass(mi.getThis()).getDeclaredFields();
		
		
		Class<?> clazz = AopProxyUtils.ultimateTargetClass(mi.getThis());
		System.out.println(clazz + " clazz:fidle" + clazz.getDeclaredFields());

		Object result = null;
		for (Field field : fields) {
			AuditNotes notes = field.getAnnotation(com.demo.security.annotation.audit.AuditNotes.class);
			if (notes != null) {
				String type = notes.type();
				System.out.println(" audit target type " + type);
				try {
					// 允许访问私有变量
					field.setAccessible(true);
					//AopUtils.isAopProxy(mi.getThis());
					//AopUtils.isCglibProxy(mi.getThis());
					//if (AopUtils.isJdkDynamicProxy(mi.getThis())) {
					//	 result = ReflectionUtils.getField(field, AopProxyUtils.ultimateTargetClass(mi.getThis()));
					//} 
					result = ReflectionUtils.getField(field, AopProxyUtils.ultimateTargetObject(mi.getThis()));
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (Throwable e) {
					e.printStackTrace();
				}
				break;
			}
		}
		System.err.println("Post-Audit " + authentication.getPrincipal() + postAuditAttribute.getAttribute() + "\n Audit :" + result);
		
		return returnObject;
	}
	
}
